
import sys
import os
import shutil

mProtocExePath = "bin/protoc.exe"
mProtocDir = ["include"]
mOutJavaDirPath = "outjava"
mOutCShareDirPath = "outcsharp"

BuildMapKey_SourceDir = "sourcesDir"
BuildMapKey_TargetDir = "targetDir"
BuildMapKey_PFilePath = "buildProtocFilePath"

OutTarget_Java = 1
OutTarget_CShare = 2


def MakeSureDirClear(dirPath,keepDir = True):
    print("MakeSureDirClear:  " + "keepDir:" + str(keepDir) + " dirPath:  " + dirPath )
    if(os.path.exists(dirPath)):
        paths = os.listdir(dirPath)
        print(paths)

        dirs = []
        for i in range(len(paths)):
            path = ChangePathSymbol(os.path.join(dirPath,paths[i]))
            if(os.path.isfile(path)):
                os.remove(path)
            else:
                dirs.append(path)

        for i in range(len(dirs)):
            _dirPath = dirs[i]
            MakeSureDirClear(_dirPath,False)

    print("MakeSureDirClear:  " + "keepDir:" + str(keepDir) + "  removedirs:  " + dirPath)
    if(not keepDir and os.path.exists(dirPath)):
        os.removedirs(dirPath)
    elif(keepDir and not os.path.exists(dirPath)):
        os.makedirs(dirPath)


def CreateDirIfNotExits(dirPath):
    if(not os.path.exists(dirPath)): os.makedirs(dirPath)


def MakeCommand(sourceDir,targetDir,protocFilePath,outTarget):
    out = " "
    if(outTarget == OutTarget_Java):
        out = out + "--java_out="
    elif(outTarget == OutTarget_CShare):
        out = out + "--csharp_out="
    else:
        print("unknow out type: " + outTarget)
        return

    CreateDirIfNotExits(targetDir)
    command = mProtocExePath + " --proto_path=" + sourceDir + out + targetDir + " " + protocFilePath
    print("MakeCommand:  " + command)
    os.system(command)


def MakeProtocFileToTargetFile(buildMapArr,outTarget):
    for i in range(len(buildMapArr)):
        buildMap = buildMapArr[i]
        tDirPath = buildMap[BuildMapKey_TargetDir]

        files = buildMap[BuildMapKey_PFilePath]
        for i in range(len(files)):
            fPath = files[i]
            MakeCommand(buildMap[BuildMapKey_SourceDir],tDirPath,fPath,outTarget)


def MakeBuildPath(protocDirPath,targetDirPath):
    files = GetProtocFilePaths(protocDirPath)
    sourceProtocDirPath = ChangePathSymbol(protocDirPath)
    buildMapArr = []
    for i in range(len(files)):
        buildProtocFilePath = files[i]
        fileDirPath = os.path.dirname(buildProtocFilePath)
        buildMap = {}
        buildMap[BuildMapKey_SourceDir] = fileDirPath

        fileDirPath = fileDirPath.replace(sourceProtocDirPath,"/")
        buildMap[BuildMapKey_TargetDir] = ChangePathSymbol(targetDirPath + fileDirPath)

        if(buildMap.get(BuildMapKey_PFilePath) == None):buildMap[BuildMapKey_PFilePath] = []
        buildMap[BuildMapKey_PFilePath].append(buildProtocFilePath)

        buildMapArr.append(buildMap)

    return buildMapArr


def GetProtocFilePaths(protocDirPath):
    fPaths = []
    for (root,dirs,files) in os.walk(protocDirPath):
        for i in range(len(files)):
            fPath = files[i]
            if(fPath.endswith(".proto")):
                fPath = ChangePathSymbol(os.path.join(root,fPath))
                fPaths.append(fPath)

    return fPaths


def ChangePathSymbol(path):
    new_path = path

    isFound = True
    while(isFound):
        index = new_path.find("\\")
        if(index == -1):
            isFound = False
        else:
            new_path = new_path.replace("\\","/")

    isFound = True
    while(isFound):
        index = new_path.find("//")
        if(index == -1):
            isFound = False
        else:
            new_path = new_path.replace("//","/")

    return new_path


def Init():
    global mProtocExePath
    global mProtocDir
    global mOutJavaDirPath
    global mOutCShareDirPath

    curDirPath = os.path.dirname(os.path.realpath(__file__))

    mProtocExePath = ChangePathSymbol(os.path.join(curDirPath,mProtocExePath))
    mOutJavaDirPath = ChangePathSymbol(os.path.join(curDirPath,mOutJavaDirPath))
    mOutCShareDirPath = ChangePathSymbol(os.path.join(curDirPath,mOutCShareDirPath))

    for i in range(len(mProtocDir)): mProtocDir[i] = ChangePathSymbol(os.path.join(curDirPath,mProtocDir[i]))


def main():
    
    Init()

    outType = OutTarget_Java
    outPath = mOutJavaDirPath

    if(len(sys.argv) == 2): outType = int(sys.argv[1])
    if(outType == OutTarget_Java): outPath = mOutJavaDirPath
    elif(outType == OutTarget_CShare):outPath = mOutCShareDirPath

    MakeSureDirClear(outPath)
    for i in range(len(mProtocDir)):
        protocDir = mProtocDir[i]
        # print("protocDir  : " + protocDir)
        buildMapArr = MakeBuildPath(protocDir,outPath)
        # print("buildMapArr  "  )
        # print(buildMapArr)
        MakeProtocFileToTargetFile(buildMapArr,outType)

main()